<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="author" content="xmy6364">
    <meta name="description" content="想要成为大佬">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />

    <link rel="shortcut icon" href="/assets/favicon.ico" type="image/x-icon">
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@600&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/highlight.js/10.5.0/styles/default.min.css">
    <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/highlight.js/10.5.0/styles/github-gist.min.css">
    <link rel="stylesheet" href="/assets/lib/css/font-awesome.min.css">
    <link rel="stylesheet" href="/assets/css/layout.css" />
    <script defer src="https://cdn.bootcdn.net/ajax/libs/clipboard.js/2.0.6/clipboard.min.js"></script>
    <script defer src="/assets/js/copyCode.js"></script>
    <script defer src="/assets/js/backTop.js"></script>
    <script defer src="/assets/js/tool.js"></script>

    
  <link rel="stylesheet" href="/assets/css/page.css" />
  <link rel="stylesheet" href="/assets/css/sidebar.css" />
  <link rel="stylesheet" href="/assets/css/footer.css" />
  <link rel="stylesheet" href="/assets/css/post.css" />
  <script defer src="/assets/js/backHome.js"></script>
  <script defer src="/assets/js/toc.js"></script>
  <script defer src="/assets/js/copyright.js"></script>


    <title>TypeScript实现设计模式——工厂模式</title>
  </head>
  <body>
    <div class="container">
      <aside>
        
  <div class="sidebar">
  <header>梦的博客</header>
  <div class="info">
    <div class="avatar">
      <img src="https://cdn.jsdelivr.net/gh/xmy6364/blog-image/img/pixelartoc_1.png" alt="头像">
    </div>
    <div class="author">xmy6364</div>
    <div class="description">想要成为大佬</div>
    <div class="about">
      <a href="/about">about me.</a>
    </div>
  </div>
  <div class="links">
    <ul>
    
      <li class="links-item">
        <a href="https://github.com/xmy6364" target="_blank">
          <i class="fa fa-github-alt" aria-hidden="true"></i>
        </a>
      </li>
    
      <li class="links-item">
        <a href="tencent://message/?uin=1176281967" target="_blank">
          <i class="fa fa-qq" aria-hidden="true"></i>
        </a>
      </li>
    
    </ul>
  </div>
  <nav>
    <ul>
    
      <li class="nav-item">
        <a href="/archives">
          <span class="nav-item__count">33</span>
          <span class="nav-item__label">归档</span>
        </a>
      </li>
    
      <li class="nav-item">
        <a href="/categories">
          <span class="nav-item__count">2</span>
          <span class="nav-item__label">分类</span>
        </a>
      </li>
    
      <li class="nav-item">
        <a href="/tags">
          <span class="nav-item__count">45</span>
          <span class="nav-item__label">标签</span>
        </a>
      </li>
    
    </ul>
  </nav>
  <div class="catalogue" id="catalogue"></div>
</div>

      </aside>
      <main>
        
  <div class="post">
    <div class="post-front">
      <h1 class="post-front__title">TypeScript实现设计模式——工厂模式</h1>
      <div class="post-front__desc">
        
        <p class="post-front__desc-date">
          <i class="fa fa-calendar" aria-hidden="true"></i>
          2020/03/20 11:47:31
        </p>
        
        
        <p class="post-front__desc-category">
          <i class="fa fa-folder-o" aria-hidden="true"></i>
          <a href="/categories/技术">
            技术
          </a>
        </p>
        
          <div class="post-front__desc-tags">
          
          <a href="/tags/TypeScript">
            <i class="fa fa-tag" aria-hidden="true"></i>
            TypeScript
          </a>
          
          <a href="/tags/设计模式">
            <i class="fa fa-tag" aria-hidden="true"></i>
            设计模式
          </a>
          
        </div>
      </div>
    </div>
    <div class="post-content">
      <nav id="toc" class="toc"><ol><li><a href="#简单工厂模式">简单工厂模式</a></li><li><a href="#工厂方法模式">工厂方法模式</a></li><li><a href="#抽象工厂模式">抽象工厂模式</a></li></ol></nav><p>上回用typescript实现了单例模式，这回来实现工厂模式。工厂模式又分为简单工厂模式、工厂方法模式以及抽象工厂模式。</p>
<h2 id="简单工厂模式">简单工厂模式</h2>
<p>简单工厂模式通常在业务比较简单的情况下使用，它有三个部分组成：工厂类、抽象产品类、具体产品类。</p>
<p><strong>抽象产品类</strong></p>
<pre class="hljs"><code><button class="copy-btn" type="button" data-clipboard-action="copy" data-clipboard-target="#copy1622200534362">复制</button><span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Pizza</span> </span>{
  <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> show(): <span class="hljs-built_in">void</span>;
  <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> cut(): <span class="hljs-built_in">void</span>;
}
<b class="name">typescript</b></code><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></pre><textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy1622200534362">abstract class Pizza {
  public abstract show(): void;
  public abstract cut(): void;
}
</textarea>
<p><strong>具体产品类</strong></p>
<pre class="hljs"><code><button class="copy-btn" type="button" data-clipboard-action="copy" data-clipboard-target="#copy1622198374146">复制</button><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">KFCPizza</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Pizza</span> </span>{
  <span class="hljs-keyword">public</span> show(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;This is KFCPizza!&#x27;</span>);
  }
  <span class="hljs-keyword">public</span> cut(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;Cut KFCPizza!&#x27;</span>);
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MCPizza</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Pizza</span> </span>{
  <span class="hljs-keyword">public</span> show(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;This is MCPizza!&#x27;</span>);
  }
  <span class="hljs-keyword">public</span> cut(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;Cut MCPizza!&#x27;</span>);
  }
}
<b class="name">typescript</b></code><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre><textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy1622198374146">class KFCPizza extends Pizza {
  public show(): void {
    console.log('This is KFCPizza!');
  }
  public cut(): void {
    console.log('Cut KFCPizza!');
  }
}

class MCPizza extends Pizza {
  public show(): void {
    console.log('This is MCPizza!');
  }
  public cut(): void {
    console.log('Cut MCPizza!');
  }
}
</textarea>
<p><strong>工厂类</strong></p>
<pre class="hljs"><code><button class="copy-btn" type="button" data-clipboard-action="copy" data-clipboard-target="#copy1622198135360">复制</button><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PizzaFactory</span> </span>{
  <span class="hljs-comment">/**
   * 静态工厂方法
   * <span class="hljs-doctag">@param </span>pizzaType 限制传入的参数为类，而非类的实例
   */</span>
  <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> createPizza(pizzaType: <span class="hljs-keyword">new</span> () =&gt; Pizza): Pizza {
    <span class="hljs-keyword">let</span> pizza = <span class="hljs-literal">null</span>;

    <span class="hljs-keyword">try</span> {
      pizza = <span class="hljs-keyword">new</span> pizzaType();
    } <span class="hljs-keyword">catch</span> (e) {
      <span class="hljs-built_in">console</span>.error(<span class="hljs-string">&#x27;Create failed!&#x27;</span>);
    }

    <span class="hljs-keyword">return</span> pizza;
  }
}
<b class="name">typescript</b></code><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre><textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy1622198135360">class PizzaFactory {
  /**
   * 静态工厂方法
   * @param pizzaType 限制传入的参数为类，而非类的实例
   */
  public static createPizza(pizzaType: new () => Pizza): Pizza {
    let pizza = null;

    try {
      pizza = new pizzaType();
    } catch (e) {
      console.error('Create failed!');
    }

    return pizza;
  }
}
</textarea>
<p><strong>测试</strong></p>
<pre class="hljs"><code><button class="copy-btn" type="button" data-clipboard-action="copy" data-clipboard-target="#copy1622197425329">复制</button><span class="hljs-keyword">let</span> pizza = PizzaFactory.createPizza(KFCPizza);
pizza.show();

pizza = PizzaFactory.createPizza(MCPizza);
pizza.show();
<b class="name">typescript</b></code><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></pre><textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy1622197425329">let pizza = PizzaFactory.createPizza(KFCPizza);
pizza.show();

pizza = PizzaFactory.createPizza(MCPizza);
pizza.show();
</textarea>
<h2 id="工厂方法模式">工厂方法模式</h2>
<p>正常情况下，简单工厂模式每次增加新的产品都需要在工厂类中增加对应的逻辑，这样就违背了开闭原则（但因为ts和我举的例子的原因体现不出这个缺点）。工厂方法模式就解决了这个问题，同时它能更好的解决复杂的业务环境。</p>
<p>工厂方法模式具有四个部分：抽象工厂类、具体工厂类、抽象产品类、具体产品类。</p>
<p><strong>抽象产品类</strong></p>
<pre class="hljs"><code><button class="copy-btn" type="button" data-clipboard-action="copy" data-clipboard-target="#copy1622201902254">复制</button><span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Pizza</span> </span>{
  <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> show(): <span class="hljs-built_in">void</span>;
  <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> cut(): <span class="hljs-built_in">void</span>;
}
<b class="name">typescript</b></code><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></pre><textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy1622201902254">abstract class Pizza {
  public abstract show(): void;
  public abstract cut(): void;
}
</textarea>
<p><strong>具体产品类</strong></p>
<pre class="hljs"><code><button class="copy-btn" type="button" data-clipboard-action="copy" data-clipboard-target="#copy1622202999337">复制</button><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">KFCPizza</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Pizza</span> </span>{
  <span class="hljs-keyword">public</span> show(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;This is KFCPizza!&#x27;</span>);
  }
  <span class="hljs-keyword">public</span> cut(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;Cut KFCPizza!&#x27;</span>);
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MCPizza</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Pizza</span> </span>{
  <span class="hljs-keyword">public</span> show(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;This is MCPizza!&#x27;</span>);
  }
  <span class="hljs-keyword">public</span> cut(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;Cut MCPizza!&#x27;</span>);
  }
}
<b class="name">typescript</b></code><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre><textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy1622202999337">class KFCPizza extends Pizza {
  public show(): void {
    console.log('This is KFCPizza!');
  }
  public cut(): void {
    console.log('Cut KFCPizza!');
  }
}

class MCPizza extends Pizza {
  public show(): void {
    console.log('This is MCPizza!');
  }
  public cut(): void {
    console.log('Cut MCPizza!');
  }
}
</textarea>
<p><strong>抽象工厂类</strong></p>
<pre class="hljs"><code><button class="copy-btn" type="button" data-clipboard-action="copy" data-clipboard-target="#copy1622200900343">复制</button><span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PizzaFactory</span> </span>{
  <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> createPizza(): Pizza;
}
<b class="name">typescript</b></code><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></pre><textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy1622200900343">abstract class PizzaFactory {
  public abstract createPizza(): Pizza;
}
</textarea>
<p><strong>具体工厂类</strong></p>
<pre class="hljs"><code><button class="copy-btn" type="button" data-clipboard-action="copy" data-clipboard-target="#copy1622198083137">复制</button><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">KFCPizzaFactory</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">PizzaFactory</span> </span>{
  <span class="hljs-keyword">public</span> createPizza(): Pizza {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> KFCPizza();
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.log(error);
    }
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MCPizzaFactory</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">PizzaFactory</span> </span>{
  <span class="hljs-keyword">public</span> createPizza(): Pizza {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> MCPizza();
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.log(error);
    }
  }
}
<b class="name">typescript</b></code><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre><textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy1622198083137">class KFCPizzaFactory extends PizzaFactory {
  public createPizza(): Pizza {
    try {
      return new KFCPizza();
    } catch (error) {
      console.log(error);
    }
  }
}

class MCPizzaFactory extends PizzaFactory {
  public createPizza(): Pizza {
    try {
      return new MCPizza();
    } catch (error) {
      console.log(error);
    }
  }
}
</textarea>
<p><strong>测试</strong></p>
<pre class="hljs"><code><button class="copy-btn" type="button" data-clipboard-action="copy" data-clipboard-target="#copy1622194295115">复制</button><span class="hljs-keyword">let</span> factory: PizzaFactory = <span class="hljs-keyword">new</span> KFCPizzaFactory();
<span class="hljs-keyword">let</span> pizza = factory.createPizza();
pizza.show();
<b class="name">typescript</b></code><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></pre><textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy1622194295115">let factory: PizzaFactory = new KFCPizzaFactory();
let pizza = factory.createPizza();
pizza.show();
</textarea>
<p>当我们需要增加新的产品时，只需要增加对应的工厂类而不需要更改原本工厂类内部的逻辑，完全符合了开闭原则。</p>
<h2 id="抽象工厂模式">抽象工厂模式</h2>
<p>学习抽象工厂模式之前，首先要先了解两个概念：<strong>产品等级结构</strong>和<strong>产品族</strong></p>
<ul>
<li>
<p><strong>产品等级结构</strong></p>
<p>产品等级结构即产品的继承结构，例如抽象的披萨类和具体某品牌的披萨类之间就构成了一个产品等级结构。</p>
</li>
<li>
<p><strong>产品族</strong></p>
<p>位于不同产品等级结构中的一组产品，功能相关联的产品组成的家族，如KFC水果披萨、MC水果披萨都是水果披萨，就可以放到同一个产品族中。</p>
</li>
</ul>
<p>抽象工厂模式具有和工厂方法模式一样的四个部分：抽象工厂类、具体工厂类、抽象产品类、具体产品类。</p>
<p><strong>抽象产品类</strong></p>
<pre class="hljs"><code><button class="copy-btn" type="button" data-clipboard-action="copy" data-clipboard-target="#copy1622194020875">复制</button><span class="hljs-comment">// KFC产品父类</span>
<span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">KFCPizza</span> </span>{
  <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> show(): <span class="hljs-built_in">void</span>;
  <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> cut(): <span class="hljs-built_in">void</span>;
}

<span class="hljs-comment">// MC产品父类</span>
<span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MCPizza</span> </span>{
  <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> show(): <span class="hljs-built_in">void</span>;
  <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> cut(): <span class="hljs-built_in">void</span>;
}
<b class="name">typescript</b></code><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre><textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy1622194020875">// KFC产品父类
abstract class KFCPizza {
  public abstract show(): void;
  public abstract cut(): void;
}

// MC产品父类
abstract class MCPizza {
  public abstract show(): void;
  public abstract cut(): void;
}
</textarea>
<p><strong>具体产品类</strong></p>
<pre class="hljs"><code><button class="copy-btn" type="button" data-clipboard-action="copy" data-clipboard-target="#copy1622200194126">复制</button><span class="hljs-comment">// 具体KFCPizza类</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">KFCFruitPizza</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">KFCPizza</span> </span>{
  <span class="hljs-keyword">public</span> show(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;This is KFCFruitPizza!&#x27;</span>);
  }
  <span class="hljs-keyword">public</span> cut(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;Cut KFCFruitPizza!&#x27;</span>);
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">KFCCheesePizza</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">KFCPizza</span> </span>{
  <span class="hljs-keyword">public</span> show(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;This is KFCCheesePizza!&#x27;</span>);
  }
  <span class="hljs-keyword">public</span> cut(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;Cut KFCCheesePizza!&#x27;</span>);
  }
}

<span class="hljs-comment">// 具体KFCPizza类</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MCFruitPizza</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">MCPizza</span> </span>{
  <span class="hljs-keyword">public</span> show(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;This is MCFruitPizza!&#x27;</span>);
  }
  <span class="hljs-keyword">public</span> cut(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;Cut MCFruitPizza!&#x27;</span>);
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MCCheesePizza</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">MCPizza</span> </span>{
  <span class="hljs-keyword">public</span> show(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;This is MCCheesePizza!&#x27;</span>);
  }
  <span class="hljs-keyword">public</span> cut(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;Cut MCCheesePizza!&#x27;</span>);
  }
}
<b class="name">typescript</b></code><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre><textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy1622200194126">// 具体KFCPizza类
class KFCFruitPizza extends KFCPizza {
  public show(): void {
    console.log('This is KFCFruitPizza!');
  }
  public cut(): void {
    console.log('Cut KFCFruitPizza!');
  }
}

class KFCCheesePizza extends KFCPizza {
  public show(): void {
    console.log('This is KFCCheesePizza!');
  }
  public cut(): void {
    console.log('Cut KFCCheesePizza!');
  }
}

// 具体KFCPizza类
class MCFruitPizza extends MCPizza {
  public show(): void {
    console.log('This is MCFruitPizza!');
  }
  public cut(): void {
    console.log('Cut MCFruitPizza!');
  }
}

class MCCheesePizza extends MCPizza {
  public show(): void {
    console.log('This is MCCheesePizza!');
  }
  public cut(): void {
    console.log('Cut MCCheesePizza!');
  }
}
</textarea>
<p><strong>抽象工厂类</strong></p>
<pre class="hljs"><code><button class="copy-btn" type="button" data-clipboard-action="copy" data-clipboard-target="#copy1622198957733">复制</button><span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PizzaFactory</span> </span>{
  <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> createKFCPizza(): KFCPizza;
  <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> createMCPizza(): MCPizza;
}
<b class="name">typescript</b></code><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></pre><textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy1622198957733">abstract class PizzaFactory {
  public abstract createKFCPizza(): KFCPizza;
  public abstract createMCPizza(): MCPizza;
}
</textarea>
<p><strong>具体工厂类</strong></p>
<pre class="hljs"><code><button class="copy-btn" type="button" data-clipboard-action="copy" data-clipboard-target="#copy1622200059645">复制</button><span class="hljs-comment">// 水果披萨工厂</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FruitPizzaFactory</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">PizzaFactory</span> </span>{
  <span class="hljs-keyword">public</span> createKFCPizza(): KFCPizza {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> KFCFruitPizza();
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.log(error);
    }
  }
  <span class="hljs-keyword">public</span> createMCPizza(): MCPizza {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> MCFruitPizza();
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.log(error);
    }
  }
}

<span class="hljs-comment">// 芝士披萨工厂</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CheesePizzaFactory</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">PizzaFactory</span> </span>{
  <span class="hljs-keyword">public</span> createKFCPizza(): KFCPizza {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> KFCCheesePizza();
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.log(error);
    }
  }
  <span class="hljs-keyword">public</span> createMCPizza(): MCPizza {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> MCCheesePizza();
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.log(error);
    }
  }
}
<b class="name">typescript</b></code><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre><textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy1622200059645">// 水果披萨工厂
class FruitPizzaFactory extends PizzaFactory {
  public createKFCPizza(): KFCPizza {
    try {
      return new KFCFruitPizza();
    } catch (error) {
      console.log(error);
    }
  }
  public createMCPizza(): MCPizza {
    try {
      return new MCFruitPizza();
    } catch (error) {
      console.log(error);
    }
  }
}

// 芝士披萨工厂
class CheesePizzaFactory extends PizzaFactory {
  public createKFCPizza(): KFCPizza {
    try {
      return new KFCCheesePizza();
    } catch (error) {
      console.log(error);
    }
  }
  public createMCPizza(): MCPizza {
    try {
      return new MCCheesePizza();
    } catch (error) {
      console.log(error);
    }
  }
}
</textarea>
<p><strong>测试</strong></p>
<pre class="hljs"><code><button class="copy-btn" type="button" data-clipboard-action="copy" data-clipboard-target="#copy1622201793646">复制</button><span class="hljs-keyword">let</span> factory: PizzaFactory = <span class="hljs-keyword">new</span> CheesePizzaFactory();
<span class="hljs-keyword">let</span> cheesePizza = factory.createKFCPizza();
cheesePizza.show();
<b class="name">typescript</b></code><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></pre><textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy1622201793646">let factory: PizzaFactory = new CheesePizzaFactory();
let cheesePizza = factory.createKFCPizza();
cheesePizza.show();
</textarea>

    </div>
    
  </div>

        <footer>
        
  <div class="footer">
  
  <div class="theme">
    博客主题为 <a href="https://github.com/xmy6364/CoinRailgun">CoinRailgun</a> 默认主题
  </div>
  <div class="copyright">
    <span>© 2019-2021 xmy6364.</span>
    <span>Powered by <a href="https://github.com/xmy6364/CoinRailgun">CoinRailgun</a></span>
  </div>
</div>

        </footer>
      </main>
    </div>
  </body>
</html>
